/***************************************************************************
 *   Copyright (C) 2008 by BogDan Vatra                                    *
 *   bogdan@licentia.eu                                                    *
 *                                                                         *
 *   This program is free software: you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation, either version 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include <QKeyEvent>
#include <QHeaderView>
#include <QSettings>
#include <QDebug>

#include "tableview.h"           
#include "database.h"
#include "query.h"

using namespace SQL;

TableView::TableView(QWidget *parent)
 : QTableView(parent)
{
	if (horizontalHeader())
		horizontalHeader()->setResizeMode(QHeaderView::Interactive);
}


const QString & TableView::queryName()
{
	return m_queryName;
}
void TableView::setQueryName(const QString & queryName)
{
	m_queryName=queryName;
	if (m_fields.size())
		setFields(m_fields);
	if (m_heads.size())
		setHeads(m_heads);
}


const QStringList & TableView::fields()
{
	return m_fields;
}
void TableView::setFields(QStringList & fields)
{
	if (Query * q=defaultDatabase()->query(m_queryName))
	{
		setModel(q->createModel(fields));
		setSelectionModel(q->createSelectionModel(model()));
		connect(q,SIGNAL(beforeInsert()),SLOT(before()));
		connect(q,SIGNAL(beforeUpdate()),SLOT(before()));
		connect(q,SIGNAL(beforeRemove()),SLOT(before()));
		connect(q,SIGNAL(afterPost()),SLOT(after()));
		connect(q,SIGNAL(afterCancel()),SLOT(after()));
	}
	m_fields=fields;
}

const QStringList & TableView::heads()
{
	return m_heads;
}
void TableView::setHeads(QStringList heads)
{
	if (dynamic_cast<QueryModel*>(model()))
		dynamic_cast<QueryModel*>(model())->setColumnNames(heads);
	m_heads=heads;
}

QString TableView::checkableField()
{
	return m_checkableField;
}
void TableView::setCheckableField(const QString & checkableField)
{
	m_checkableField=checkableField;
	if (dynamic_cast<QueryModel*>(model()))
		dynamic_cast<QueryModel*>(model())->setCheckableColumn(m_checkableField);
}

QString TableView::keyField()
{
	return m_keyField;
}
void TableView::setKeyField(const QString &keyField)
{
	m_keyField=keyField;
}

QString TableView::arrayOfCheckedFileds()
{
	QString array;
	QString field=m_keyField.length()?m_keyField:m_checkableField;
	Query * q=defaultDatabase()->query(m_queryName);
	if (!q || !q->size())
		return array;
	const QList<QSqlRecord> & res=q->result();
	bool fieldIsNumber=Query::typeIsNumber(res[0].value(field).type());
	if (dynamic_cast<QueryModel*>(model()))
	{
		const QVector<bool> & cr=dynamic_cast<QueryModel*>(model())->checkedRows();
		array="{";
		bool first=true;
		for(int cf=0;cf<res.size() && cf<cr.size();cf++)
		{
			if (!cr[cf])
				continue;
			if (!first)
				array+=",";
			if (fieldIsNumber)
				array+=res[cf].value(field).toString();
			else
				array+="\""+res[cf].value(field).toString()+"\"";
			first=false;
		}
		if (first)
			array="NULL";
		else
			array+="}";
	}
	return array;
}

QString TableView::nameOfCheckedFileds()
{
	QString array;	
	QString field=m_fields.at( 0 );	
	Query * q=defaultDatabase()->query(m_queryName);
	if (!q || !q->size())
		return array;
	const QList<QSqlRecord> & res=q->result();
	bool fieldIsNumber=Query::typeIsNumber(res[0].value(field).type());
	if (dynamic_cast<QueryModel*>(model()))
	{
		const QVector<bool> & cr=dynamic_cast<QueryModel*>(model())->checkedRows();		
		bool first=true;
		for(int cf=0;cf<res.size() && cf<cr.size();cf++)
		{
			if (!cr[cf])
				continue;
			if (!first)
				array+=",";			
				array+=res[cf].value(field).toString();			
			first=false;
		}
		if (first)
			array="NULL";		
	}
	return array;
}

void TableView::checkAll()
{
	if (dynamic_cast<QueryModel*>(model()))
		dynamic_cast<QueryModel*>(model())->checkAll();
}
void TableView::unckeckAll()
{
	if (dynamic_cast<QueryModel*>(model()))
		dynamic_cast<QueryModel*>(model())->uncheckAll();
}
void TableView::before()
{
	setEnabled(false);
}
void TableView::after()
{
	setEnabled(true);
}

QString TableView::uniqueName()
{
	QString name=objectName();;
	QObject *parent=QObject::parent();
	while(parent)
	{
		name+="_"+parent->objectName();
		parent=parent->parent();
	}
	return name;
}

void TableView::showEvent(QShowEvent * event)
{
	QTableView::showEvent(event);
	if (!event->isAccepted())
		return;

	QSettings s;
	QString keyname=uniqueName();
	for (int i=0;i<m_heads.size();i++)
	{
		if (s.value(keyname+QString("/%1").arg(i),"0").toInt())
			setColumnWidth(i, s.value(keyname+QString("/%1").arg(i),"0").toInt());
		else
			resizeColumnToContents(i);
	}
}

void TableView::hideEvent ( QHideEvent * event )
{
	QTableView::hideEvent(event);
	if (!event->isAccepted())
		return;
	QSettings s;
	QString keyname=uniqueName();
	for (int i=0;i<m_fields.size();i++)
		s.setValue(keyname+QString("/%1").arg(i),columnWidth(i));
}

void TableView::keyPressEvent(QKeyEvent * event)
{
	switch(event->key())
	{
		case Qt::Key_Return:
		case Qt::Key_Enter:
			emit(returnPressed());
			break;

		case Qt::Key_Escape:
			emit(escapePressed());
			break;

		case Qt::Key_Insert:
			emit(insertPressed());
			break;

		case Qt::Key_Delete:
			emit(deletePressed());
			break;
	}
	QTableView::keyPressEvent(event);
}

void TableView::focusInEvent(QFocusEvent * event)
{
	QTableView::focusInEvent(event);
	if (event->isAccepted())
		emit(focusIn());
}

void TableView::focusOutEvent(QFocusEvent * event)
{
	QTableView::focusOutEvent(event);
	if (event->isAccepted())
		emit(focusOut());
}
